/* -----------------
* brief
* 1. this is code gen by tools
* 2. mvc code are driver by the model defined with the same filename,
	 for example:
	 there is a Xmodel struct define in xmodel.go file, after the script run (lego model-mvc module_name xmodel)
     it will auto create the code under the module's path
	 m --> xmodel.go
	 v --> view
	 c --> xmodel_ctrl
* 3. you should modify this code if it doesn't satisfy your purpose
*/

package controller

import (
	"encoding/json"
	"fmt"
	"github.com/mjiulee/lego"
	"github.com/mjiulee/lego/utils"
	"github.com/valyala/fasthttp"
	"saas_sys_base/common"

	. "saas_sys_base/modules/eshop/service"

	. "saas_sys_base/modules/appmanager/models"
	. "saas_sys_base/modules/appmanager/service"
)

type AppProductCtrl struct {

	service     AppProductService
	appAttrService     AppAttrService
	appSuitService     AppSuitService
	appSpecService AppProductSpecService
	shopService EShopService
}

func init() {
	vc := new(AppProductCtrl)
	_ctrlList = append(_ctrlList, vc)
}

func (vc *AppProductCtrl) CtrlInfo() string {
	return "AppProductCtrl"
}

func (vc *AppProductCtrl) RoutInit() {
	// 列表页面
	lego.GET("/admin/AppProduct/listpage", vc.ListPage, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/AppProduct/listjson", vc.ListJson, lego.LEGO_SESSION_TYPE_ADMIN, true)
	// 编辑页面
	lego.GET("/admin/AppProduct/editpage", vc.GetEditPage, lego.LEGO_SESSION_TYPE_ADMIN, true)
	//lego.POST("/admin/AppProduct/editpage", vc.PostEditPage, lego.LEGO_SESSION_TYPE_ADMIN, false)

	// 列表页面
	lego.GET("/admin/AppProduct/listpage_app", vc.ListPage_App, lego.LEGO_SESSION_TYPE_WEB, true)
	lego.GET("/admin/AppProduct/listjson_app", vc.ListJson_App, lego.LEGO_SESSION_TYPE_WEB, true)

	// 编辑页面
	lego.GET("/admin/AppProduct/editpage_app", vc.GetEditPage_App, lego.LEGO_SESSION_TYPE_WEB, true)
	lego.POST("/admin/AppProduct/editpage", vc.PostEditPage, lego.LEGO_SESSION_TYPE_WEB, true)

	// 删除
	lego.POST("/admin/AppProduct/del", vc.DelRecode, lego.LEGO_SESSION_TYPE_WEB, true)

	//商家小程序
	lego.APIGET("/api/AppProduct/listjson_app", vc.ListJson_App_For_Api, true)

	lego.APIPOST("/api/AppProduct/editorcreate", vc.PostEditPage, true)

	lego.APIPOST("/api/AppProduct/del", vc.DelRecode, true)

	//lego.APIPOST("/api/AppProduct/setOnSale", vc.SetOnSale, true)

	//lego.APIPOST("/api/AppProduct/setOffSale", vc.SetOffSale, true)

	lego.APIGET("/api/AppProduct/getTenantProductDetail", vc.GetTenantProductDetail, true)

	//用户小程序端
	//lego.APIGET("/api/Mall/AppProduct/listjson", vc.GetProductListForMall, true)

	//lego.APIGET("/api/Mall/AppProduct/getProductDetail", vc.GetProductDetailForMall, true)

}

/* 列表接口
* params:
  ---
*/
func (vc *AppProductCtrl) ListJson(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		//:saas管理端使用代码，使用时将注释解开 sessionData := common.GetSessionData(&ctxExt)
		//:appwho := sessionData.AppTokenWho

		// 表单校验
		type ReqParams struct {
			Keyword string // 关键字查询
			Page    int    `vd:"$>0"` // 分页
			PSize   int    `vd:"$>0"`  // 分页大小

			OrderField string
			Order      string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			Keyword:    string(ctxExt.Peek("keyword")),
			Page:       utils.BytesToInt(ctxExt.Peek("page")),
			PSize:      utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField: string(ctxExt.Peek("order_field")),
			Order:      string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		// 业务查询
		if list, total, err := vc.service.ListAppProduct(req.Keyword, req.Page, req.PSize, req.OrderField, req.Order); err != nil {
			code = 100
			msg = "fail"
			lego.LogError(err)
		} else {
			response["count"] = total
			response["data"] = list
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppProductCtrl) ListPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("appmanager/view/AppProduct/list.html", data)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppProductCtrl) GetEditPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetAppProductByIdAndMiniAppId(req.Id, appwho.MiniAppId)
		data["detail"] = target
		break
	}
	ctxExt.HTML("appmanager/view/AppProduct/edit.html", data)
	return
}

/* 数据编辑
* params:
  ---
*/
func (vc *AppProductCtrl) PostEditPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	data := make(map[string]interface{})

	code := 0
	msg := ""

	sessionData := common.GetSessionData(&ctxExt) //
	appwho := sessionData.AppTokenWho

	for {


		type SpecParams struct {
			Id        int64   `json:"id,string"`
			SpecName  string  `json:"spec_name"`
			SellPrice float64 `json:"sell_price"`
			Stock     int     `json:"stock"`
			Months    int     `json:"months"`
		}

		// 表单校验
		type ReqParams struct {
			//#ModelEditFormDefined#
			Id           int64        `json:"id,string"`
			ProductName  string       `json:"product_name"`
			DefaultImage string       `json:"defaultImage"`
			Video        string       `json:"video,omitempty"`
			Postage      int64      `json:",string"`
			Description  string       `json:"description,omitempty"`
			IfSale       int          `json:"if_sale,string"`
			SpecList     []SpecParams `json:"speclist"`

			//MiniAppIdForSale int64 `json:"mini_app_id_for_sale,string"`
			AppSuitCode int64 `json:"app_suit_code,string"`
		}

		var req ReqParams
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &req)
		if err != nil {
			code = 100
			msg = fmt.Sprintf("参数错误, %s", err.Error())
			break
		}

		if req.SpecList == nil || len(req.SpecList) == 0 {
			code = 100
			msg = "参数错误"
			break
		}


		appsuit := vc.appSuitService.GetAppSuitBySuitCode(req.AppSuitCode)
		if appsuit == nil {
			code = 100
			msg = fmt.Sprintf("套餐不存在<AppSuitCode:%d>", appsuit.AppSuitCode)
			break
		}
		// 业务处理
		recode := vc.service.GetAppProductByIdAndMiniAppId(req.Id, appwho.MiniAppId)
		if recode == nil {
			// 新建
			recode := new(AppProduct)
			//#ModelFiledMapper#'
			recode.Id = req.Id
			recode.ProductName = req.ProductName
			recode.DefaultImage = req.DefaultImage
			recode.Video = req.Video
			recode.Postage = req.Postage
			recode.Description = req.Description
			recode.IfSale = req.IfSale
			recode.MiniAppId = appwho.MiniAppId //注意，区分卖方是哪个app
			//recode.MiniAppIdForSale = req.MiniAppIdForSale
			recode.AppSuitCode = appsuit.AppSuitCode
			recode.AppSuitId = appsuit.Id
			//recode.EShopId = req.EShopId
			//recode.TenantId = appwho.TenantId

			if false == vc.service.SaveAppProduct(recode) {
				code = 100
				msg = "false"
				break
			}
			for _, spec := range req.SpecList {
				dbSpec := new(AppProductSpec)
				dbSpec.ProductId = recode.Id
				dbSpec.SellPrice = spec.SellPrice
				dbSpec.SpecName = spec.SpecName
				dbSpec.Stock = spec.Stock
				dbSpec.Months = spec.Months
				vc.appSpecService.SaveAppProductSpec(dbSpec)
			}

		} else {
			//#ModelFiledMapper#
			recode.Id = req.Id
			recode.ProductName = req.ProductName
			recode.DefaultImage = req.DefaultImage
			recode.Video = req.Video
			recode.Postage = req.Postage
			recode.Description = req.Description
			recode.IfSale = req.IfSale
			//recode.MiniAppId = req.MiniAppId 这两个值不能编辑，只能先建的时候配置
			//recode.MiniAppIdForSale = req.MiniAppIdForSale 这两个值不能编辑，只能先建的时候配置

			if false == vc.service.UpdateAppProduct(recode) {
				code = 100
				msg = "false"
				break
			}

			dbSpecList := vc.appSpecService.ListByProductId(recode.Id)
			for _, dbSpec := range dbSpecList {
				anyFlag, err := utils.SliceAny(req.SpecList, func(elem interface{}) bool {
					v := elem.(SpecParams)
					if v.Id == dbSpec.Id {
						return true
					}
					return false
				})
				if err != nil {
					code = 100
					msg = "参数错误"
					break
				}
				if !anyFlag {
					dbSpec.IfDel = 1
					vc.appSpecService.DelAppProductSpecById(dbSpec.Id)
				}
			}

			for _, spec := range req.SpecList {
				findResult, err := utils.SliceFindWhere(dbSpecList, func(elem interface{}) bool {
					v := elem.(*AppProductSpec)
					if v.Id == spec.Id && v.IfDel == 0 {
						return true
					}
					return false
				})
				if err != nil {
					code = 100
					msg = "参数错误"
					break
				}

				existDbSpecs := findResult.([]*AppProductSpec)

				if existDbSpecs == nil || len(existDbSpecs) == 0 {
					//新增操作
					dbSpec := new(AppProductSpec)
					dbSpec.ProductId = recode.Id
					dbSpec.SellPrice = spec.SellPrice
					dbSpec.SpecName = spec.SpecName
					dbSpec.Stock = spec.Stock
					dbSpec.Months = spec.Months
					vc.appSpecService.SaveAppProductSpec(dbSpec)
				} else {
					//修改操作
					dbSpec := existDbSpecs[0]
					dbSpec.SellPrice = spec.SellPrice
					dbSpec.SpecName = spec.SpecName
					dbSpec.Stock = spec.Stock
					dbSpec.Months = spec.Months
					vc.appSpecService.UpdateAppProductSpec(dbSpec)
				}

			}

		}
		break
	}
	response["code"] = code
	response["msg"] = msg
	response["data"] = data
	ctxExt.JSON(200, response)
	return
}

/* 删除数据记录
* params:
  ---
*/
func (vc *AppProductCtrl) DelRecode(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	data := make(map[string]interface{})

	code := 0
	msg := ""


	sessionData := common.GetSessionData(&ctxExt) //
	appwho := sessionData.AppTokenWho

	for {
		// 表单校验
		type ReqParams struct {
			Id int64 `json:"id,string"` // 记录id
		}
		//req := ReqParams{
		//	Id: utils.BytesToInt64(ctxExt.Peek("id")),
		//}
		//if err := lego.Validate(req); err != nil {
		//	code = 100
		//	msg = "参数错误"
		//	break
		//}

		var req ReqParams
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &req)

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		// 业务删除
		target := vc.service.GetAppProductByIdAndMiniAppId(req.Id, appwho.MiniAppId)
		if target == nil {
			code = 100
			msg = "记录不存在"
			break
		}

		if false == vc.service.DelAppProductById(target.Id) {
			code = 100
			msg = "操作失败"
			break
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	response["data"] = data
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppProductCtrl) ListPage_App(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("appmanager/view/AppProduct/list_app.html", data)
	return
}

/* 列表接口
* params:
  ---
*/
func (vc *AppProductCtrl) ListJson_App(ctx *fasthttp.RequestCtx) {
 	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		//:saas管理端使用代码，使用时将注释解开 sessionData := common.GetSessionData(&ctxExt)
		//:appwho := sessionData.AppTokenWho
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		// 表单校验
		type ReqParams struct {
			Keyword string // 关键字查询
			Page    int    `vd:"$>0"` // 分页
			PSize   int    `vd:"$>0"`  // 分页大小

			OrderField string
			Order      string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			Keyword:    string(ctxExt.Peek("keyword")),
			Page:       utils.BytesToInt(ctxExt.Peek("page")),
			PSize:      utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField: string(ctxExt.Peek("order_field")),
			Order:      string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		// 业务查询
		if list, total, err := vc.service.ListAppProductByWho(appwho, req.Keyword, req.Page, req.PSize, req.OrderField, req.Order); err != nil {
			code = 100
			msg = "fail"
			lego.LogError(err)
		} else {
			response["count"] = total
			response["data"] = list
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

func (vc *AppProductCtrl) ListJson_App_For_Api(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		//:saas管理端使用代码，使用时将注释解开 sessionData := common.GetSessionData(&ctxExt)
		//:appwho := sessionData.AppTokenWho
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		// 表单校验
		type ReqParams struct {
			Keyword string // 关键字查询
			Page    int    `vd:"$>0"` // 分页
			PSize   int    `vd:"$>0"`  // 分页大小

			OrderField string
			Order      string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			Keyword:    string(ctxExt.Peek("keyword")),
			Page:       utils.BytesToInt(ctxExt.Peek("page")),
			PSize:      utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField: string(ctxExt.Peek("order_field")),
			Order:      string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		// 业务查询
		condiBean := &AppProduct{IfSale: common.STATE_YES} //只查询正在销售的
		list, total, err := vc.service.ListAppProductByWho2(appwho, req.Page, req.PSize, condiBean)
		if err != nil {
			code = 100
			msg = "fail"
			lego.LogError(err)
			break
		}

		for i, item := range list {
			list[i].Specs = vc.appSpecService.ListByProductId(item.Id)
		}


		response["count"] = total
		response["data"] = list

		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppProductCtrl) GetEditPage_App(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetAppProductByIdAndMiniAppId(req.Id, appwho.MiniAppId)

		//applist, _, _ := vc.appAttrService.ListAppAttr2(0, 100) //先写死100，仅支持100个微应用列表
		appsuit, _, _ := vc.appSuitService.List("", 1, 100)
		//speclist := vc.specService.ListByProductId(req.Id)

		data["detail"] = target
		data["appsuit"] = appsuit //渲染菜单使用
		//data["speclist"] = speclist
 		break
	}
	ctxExt.HTML("appmanager/view/AppProduct/edit_app.html", data)
	return
}

func (vc *AppProductCtrl) GetTenantProductDetail(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetAppProductByIdAndMiniAppId(req.Id, appwho.MiniAppId)
		target.Specs = vc.appSpecService.ListByProductId(req.Id)
		response["product"] = target

		//response["specs"] = vc.appSpecService.ListByProductId(req.Id)
		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

